package com.qinghe.pro.service.main.impl;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.qinghe.pro.entity.main.Module;
import com.qinghe.pro.exception.ExistedException;
import com.qinghe.pro.exception.NotDeletedException;
import com.qinghe.pro.mapper.main.ModuleMapper;
import com.qinghe.pro.service.main.ModuleService;

@Service("moduleServiceImpl")
public class ModuleServiceImpl implements ModuleService {

	@Autowired
	private ModuleMapper moduleMapper;

	@Override
	public Module get(Integer id) {
		return moduleMapper.selectByPrimaryKey(id);
	}

	@Override
	public void insert(Module module) {
		if (moduleMapper.selectBySn(module.getSn()) != null) {
			throw new ExistedException("已存在授权名称为" + module.getSn() + "的模块。");
		}

		moduleMapper.insertSelective(module);
	}

	@Override
	public void update(Module module) {
		moduleMapper.updateByPrimaryKeySelective(module);
	}

	/**
	 * 判断是否是根模块.
	 */
	private boolean isRoot(Integer id) {
		return id == 1;
	}

	@Override
	public void delete(Integer id) {
		if (isRoot(id)) {
			throw new NotDeletedException("不允许删除根模块。");
		}

		Module module = this.get(id);

		// 先判断是否存在子模块，如果存在子模块，则不允许删除
		if (module.getChildren().size() > 0) {
			throw new NotDeletedException(module.getName() + "模块下存在子模块，不允许删除。");
		}

		moduleMapper.deleteByPrimaryKey(id);
	}

	@Override
	//@RedisCache(type = Module.class)
	public Module getTree() {
		List<Module> list = moduleMapper.selectAll();

		List<Module> rootList = makeTree(list);

		return rootList.get(0);
	}

	private List<Module> makeTree(List<Module> list) {
		List<Module> parent = new ArrayList<Module>();
		// get parentId = null;
		for (Module e : list) {
			if (e.getParentId() == null) {
				e.setChildren(new ArrayList<Module>(0));
				parent.add(e);
			}
		}
		// 删除parentId = null;
		list.removeAll(parent);

		makeChildren(parent, list);

		return parent;
	}

	private void makeChildren(List<Module> parent, List<Module> children) {
		if (children.isEmpty()) {
			return;
		}

		List<Module> tmp = new ArrayList<Module>();
		for (Module c1 : parent) {
			for (Module c2 : children) {
				c2.setChildren(new ArrayList<Module>(0));
				if (c1.getId().equals(c2.getParentId())) {
					c1.getChildren().add(c2);
					tmp.add(c2);
				}
			}
		}

		children.removeAll(tmp);

		makeChildren(tmp, children);
	}

}
